<template>
  <transition name="window-close">
    <div
      :id="winInfo.wid + ''"
      class="win-content"
      v-show="winInfo.isShow"
      :style="{
        top: `${winInfo.layerY}px`,
        left: `${winInfo.layerX}px`,
        width: `${winSize.width}px`,
        height: `${winSize.height}px`,
        minWidth: `${winSize.minWidth}px`,
        minHeight: `${winSize.minHeight}px`,
        zIndex: winInfo.zIndex
      }"
      ref="winRef"
      @click="winContentClick(winInfo.wid)"
    >
      <div class="title unselect" @dragend="dragEnd($event, winInfo.wid)" draggable="true">
        <div class="title-left">
          <el-image :src="winInfo.imgUrl" style="width: 16px; height: 16px; marginRight: 10px" />
          <span>{{ winInfo.name }}</span>
        </div>
        <div class="title-right">
          <el-icon class="min" @click.stop="minWin(winInfo.wid)"><Minus /></el-icon>
          <el-image
            class="max"
            v-if="!isWinMax"
            :src="amplificateImg"
            style="width: 16px; height: 16px"
            @click.stop="maxWin(winInfo.wid)"
          />
          <el-image
            class="normal"
            v-else
            :src="narrowImg"
            style="width: 16px; height: 16px"
            @click.stop="maxWin(winInfo.wid)"
          />
          <el-icon class="close" @click.stop="closeWin(winInfo.wid)"><Close /></el-icon>
        </div>
      </div>
      <div class="win-panel">
        <el-scrollbar style="height: 100%" wrapStyle="overflow-x:hidden;">
          <!-- <router-view :key="route.path" :name="winInfo.path.split('/').pop()" /> -->
          <template v-if="winInfo.pageUrl">
            <Iframe :pageUrl="winInfo.pageUrl" :wid="winInfo.wid + ''" />
          </template>
          <template v-else>
            <keep-alive>
              <component :is="currentCpn" :wid="winInfo.wid + ''" />
            </keep-alive>
          </template>
        </el-scrollbar>
      </div>
    </div>
  </transition>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue'
import type { PropType } from 'vue'

import { useWindowStore } from '@/store/window'
import { useSysStore } from '@/store/sys'

import H2C from 'html2canvas'
import { Minus, Close } from '@element-plus/icons-vue'

import { IWinConfig } from './type'
import amplificateImg from '@/assets/img/win-content/fangda.png'
import narrowImg from '@/assets/img/win-content/suoxiao.png'
import Iframe from '@/views/iframe/iframe.vue'

import { useAsyncCpn } from './hooks/use-async-cpn'
import { useSetWinTop } from './hooks/use-set-win-top'
import { useCloseWin } from '@/hooks/use-close-win'

const props = defineProps({
  winInfo: {
    type: Object as PropType<IWinConfig>,
    required: true
  }
})

const windowStore = useWindowStore()
const sysStore = useSysStore()

// 导入所有异步组件：即需要展示的组件
const { cpns } = useAsyncCpn()
// 打开的图标名称与所有异步组件进行匹配，并使用动态组件展示，如果是由pageUrl属性则展示Iframe组件
const name = props.winInfo.path.split('/').pop()
const currentCpn = ref()
const result = cpns.find(cpn => cpn.name === name)
currentCpn.value = result?.cpn

const winSize = reactive({
  height: sysStore.winSize.height,
  width: sysStore.winSize.width,
  minHeight: sysStore.winSize.minHeight,
  minWidth: sysStore.winSize.minWidth
})
const winRef = ref<InstanceType<typeof HTMLElement>>()
const isWinMax = ref(false) // 窗口是否为最大化

// 窗口X Y位置
const layer = reactive({
  x: props.winInfo.layerX,
  y: props.winInfo.layerY
})

// 最小化
const minWin = (wid: number) => {
  const index = windowStore.winConfigs.findIndex((item) => item.wid === wid)
  // 把缩略图添加进去，以便鼠标移动到nav-bottom小图标上查看
  createMinImg()
  windowStore.winConfigs[index].isShow = false
  windowStore.winConfigs[index].zIndex = 0
}

// 最大化
const maxWin = (wid: number) => {
  const windowH = windowStore.h
  const windowW = windowStore.w
  // 将窗口置顶
  const index = useSetWinTop(wid)
  if (isWinMax.value) {
    // 放大
    winSize.height = sysStore.winSize.height
    winSize.width = sysStore.winSize.width
    windowStore.winConfigs[index].layerX = layer.x
    windowStore.winConfigs[index].layerY = layer.y
    winRef.value!.className = 'win-content transition_ani'
    setTimeout(() => { winRef.value!.className = 'win-content' }, 1500)
  } else {
    // 正常状态
    winSize.height = windowH - 34
    winSize.width = windowW
    windowStore.winConfigs[index].layerX = 0
    windowStore.winConfigs[index].layerY = 0
    winRef.value!.className = 'win-content transition_ani'
    setTimeout(() => { winRef.value!.className = 'win-content' }, 1500)
  }
  isWinMax.value = !isWinMax.value
}

// 关闭，从数组中删除
const closeWin = (wid: number) => { useCloseWin(wid) }

// 拖拽
const dragEnd = (e: any, wid: number) => {
  const index = useSetWinTop(wid)
  windowStore.winConfigs[index].layerX = e.clientX - (winSize.width / 2)
  windowStore.winConfigs[index].layerY = e.clientY - 18
}

// 点击选中当前win
const winContentClick = (wid: number) => {
  const index = useSetWinTop(wid)
  windowStore.currentActiveId = props.winInfo.wid
}

// 组件被创建后，生成缩略图
const createMinImg = () => {
  // 生成缩略图
  H2C(document.getElementById(props.winInfo.wid+'')!).then(cvs => {
    const index = windowStore.winConfigs.findIndex((item) => item.wid === props.winInfo.wid)
    const minImg = cvs.toDataURL()
    windowStore.winConfigs[index].minImg = minImg
  })
}
onMounted(() => {
  // 本想使用nextTick作为执行的，但发现执行还是太快了数据还没渲染完成就绘制完成，故用setTimeout
  setTimeout(() => createMinImg(), 500)
})
</script>

<style lang="less" scoped>
.win-content {
  position: absolute;
  display: inline-block;
  border-radius: 5px;
  overflow: hidden;
  box-shadow: 0px 1px 2px -2px rgba(32, 32, 32, 0.16);
  background-color: rgba(188, 211, 221, 0.9);

  .title {
    display: flex;
    width: 100%;
    height: 36px;
    backdrop-filter: blur(15px);
    line-height: 36px;
    border-radius: 5px 5px 0px 0px;
    background: rgba(221, 221, 221, 0.836);
    &:hover {
      cursor: move;
    }

    .title-left {
      display: inline-block;
      width: calc(100% - 80px);
      height: 36px;
      padding: 6px 10px;
      box-sizing: border-box;
      font-weight: 600;
      span {
        position: relative;
        top: -2px;
      }
    }
    .title-right {
      display: inline-block;
      width: 76px;
      height: 24px;
      padding: 6px 0px;
      text-align: center;

      .min,
      .max,
      .normal,
      .close {
        margin: 0 4px;
      }
      .min:hover {
        background: rgba(4, 4, 4, 0.2);
        color: #ffffff;
        cursor: pointer;
      }
      .max:hover {
        background: rgba(4, 4, 4, 0.2);
        color: #ffffff;
        cursor: pointer;
      }
      .normal:hover {
        background: rgba(4, 4, 4, 0.2);
        color: #ffffff;
        cursor: pointer;
      }
      .close:hover {
        background: rgba(255, 9, 9, 0.8);
        color: #ffffff;
        cursor: pointer;
      }
    }
  }
  .win-panel {
    height: calc(100% - 36px);
    :deep(.el-scrollbar__view) {
      height: 100%;
    }
  }
}

.transition_ani {
  transition: all .4s ease-in-out;
}
</style>
